package org.yelongframework.poi;

import java.util.Iterator;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;

/**
 * 默认实现
 * 
 * @since 1.0.0
 */
public class DefaultPOIExcelSupport implements POIExcelSupport {

	private final CellValueStringReader cellValueStringReader = new DefaultCellValueStringReader();

	// ==================================================隐藏sheet页==================================================

	@Override
	public void setSheetHidden(Workbook workbook, int sheetIndex, boolean hidden) {
		workbook.setSheetHidden(sheetIndex, hidden);
	}

	// ==================================================重复数据单元格合并==================================================

	@Override
	public void dataColEqualsMerge(Sheet sheet, int columnIndex, int beginRow) {
		int lastRowNum = sheet.getLastRowNum();
		if (beginRow == lastRowNum) {
			return;
		}
		// 上一个单元格的值
		String prevValue = null;
		// 第一个相同值的起始行
		int prevValueFirstRowIndex = -1;
		for (int i = beginRow; i <= lastRowNum; i++) {
			Row row = sheet.getRow(i);
			Cell cell = row.getCell(columnIndex);
			String cellValue = cell.getStringCellValue();
			// 如果是起始行直接设置值和索引
			if (i == beginRow) {
				prevValue = cellValue;
				prevValueFirstRowIndex = i;
				continue;
			}
			boolean isLastRow = i == lastRowNum;// 是否是最后一行

			if (isLastRow) {// 如果是最后一行
				// 最后一行值与上面一行值相同的情况
				if (StringUtils.isNotBlank(cellValue) && cellValue.equals(prevValue)) {
					sheet.addMergedRegion(new CellRangeAddress(prevValueFirstRowIndex, i, columnIndex, columnIndex));
					break;
				} else if (prevValueFirstRowIndex != i) {// 倒数第二行与倒数第二行之前的值相同，合并倒数第二行与之前的行
					sheet.addMergedRegion(
							new CellRangeAddress(prevValueFirstRowIndex, i - 1, columnIndex, columnIndex));
					break;
				}
			} else {// 不是最后一行
				// 如果当前行的单元格值与上一行单元格的值相同则跳过
				if (StringUtils.isNotBlank(cellValue) && cellValue.equals(prevValue)) {
					continue;
				}
				// 如果当前行的单元格值与上一行单元格的值不相同时将第一个开始相同的值到最后一个相同的值的行进行合并
				sheet.addMergedRegion(new CellRangeAddress(prevValueFirstRowIndex, i - 1, columnIndex, columnIndex));
				prevValue = cellValue;
				prevValueFirstRowIndex = i;
			}
		}
	}

	// ==================================================单元格设置值==================================================

	@Override
	public void setValue(Sheet sheet, int rowIndex, int columnIndex, String value) {
		Row row = sheet.getRow(rowIndex);
		if (null == row) {
			row = sheet.createRow(rowIndex);
		}
		Cell cell = row.getCell(columnIndex);
		if (null == cell) {
			cell = row.createCell(columnIndex);
		}
		cell.setCellValue(value);
	}

	@Override
	public String getValueString(Cell cell) {
		return cellValueStringReader.apply(cell);
	}

	// ==================================================复制sheet==================================================

	@Override
	public void copySheet(Workbook workbook, Sheet srcSheet, Sheet destSheet) {
		// 合并区域处理
		mergerRegion(srcSheet, destSheet);
		for (Iterator<Row> rowIt = srcSheet.rowIterator(); rowIt.hasNext();) {
			Row srcRow = (Row) rowIt.next();
			Row newRow = destSheet.createRow(srcRow.getRowNum());
			short firstCellNum = srcRow.getFirstCellNum();
			short lastCellNum = srcRow.getLastCellNum();
			for (int i = firstCellNum; i <= lastCellNum; i++) {
				int srcColumnWidth = srcSheet.getColumnWidth(i);
				destSheet.setColumnWidth(i, srcColumnWidth);
				destSheet.setColumnHidden(i, false);
			}
			// 行复制
			copyRow(workbook, srcRow, newRow);
		}
	}

	// ==================================================复制行==================================================

	@Override
	public void copyRow(Workbook workbook, Row srcRow, Row destRow) {
		destRow.setHeightInPoints(srcRow.getHeightInPoints());
		for (Iterator<Cell> cellIt = srcRow.cellIterator(); cellIt.hasNext();) {
			Cell tmpCell = cellIt.next();
			Cell newCell = destRow.createCell(tmpCell.getColumnIndex());
			copyCell(workbook, tmpCell, newCell);
		}
	}

	@Override
	public void copyRows(Sheet srcSheet, Sheet destSheet, int startRowIndex, int endRowIndex, int position) {
		int pStartRow = startRowIndex - 1;
		int pEndRow = endRowIndex - 1;
		int pPosition = position - 1;
		int i, j;
		Row sourceRow = null, targetRow = null;
		Cell sourceCell = null, targetCell = null;
		if ((pStartRow < 0) || (pEndRow < 0)) {
			return;
		}
		// 移动行
		if (startRowIndex < destSheet.getLastRowNum()) {
			destSheet.shiftRows(startRowIndex, destSheet.getLastRowNum(), endRowIndex - startRowIndex + 1, true, false);
		}
		// 拷贝行
		for (i = pStartRow; i <= pEndRow; i++) {
			sourceRow = srcSheet.getRow(i);
			if (sourceRow == null) {
				continue;
			}
			targetRow = destSheet.createRow(i - pStartRow + pPosition);
			targetRow.setHeight(sourceRow.getHeight());
			for (j = sourceRow.getFirstCellNum(); j < sourceRow.getPhysicalNumberOfCells(); j++) {
				sourceCell = sourceRow.getCell(j);
				if (sourceCell == null) {
					continue;
				}
				targetCell = targetRow.createCell(j);
				targetCell.setCellStyle(sourceCell.getCellStyle());
			}
		}
	}

	// ==================================================复制单元格==================================================

	@Override
	public void copyCell(Workbook workbook, Cell srcCell, Cell destCell) {
		destCell.setCellStyle(srcCell.getCellStyle());
		// 评论
		if (srcCell.getCellComment() != null) {
			destCell.setCellComment(srcCell.getCellComment());
		}
		// 不同数据类型处理
		int srcCellType = srcCell.getCellType();
		destCell.setCellType(srcCellType);
		boolean copyValueFlag = true;
		if (copyValueFlag) {
			if (srcCellType == Cell.CELL_TYPE_NUMERIC) {
				if (DateUtil.isCellDateFormatted(srcCell)) {
					destCell.setCellValue(srcCell.getDateCellValue());
				} else {
					destCell.setCellValue(srcCell.getNumericCellValue());
				}
			} else if (srcCellType == Cell.CELL_TYPE_STRING) {
				destCell.setCellValue(srcCell.getRichStringCellValue());
			} else if (srcCellType == Cell.CELL_TYPE_BLANK) {
				// nothing21
			} else if (srcCellType == Cell.CELL_TYPE_BOOLEAN) {
				destCell.setCellValue(srcCell.getBooleanCellValue());
			} else if (srcCellType == Cell.CELL_TYPE_ERROR) {
				destCell.setCellErrorValue(srcCell.getErrorCellValue());
			} else if (srcCellType == Cell.CELL_TYPE_FORMULA) {
				destCell.setCellFormula(srcCell.getCellFormula());
			} else { // nothing29
			}
		}
	}

	// ==================================================support==================================================

	/**
	 * 合并区域
	 * 
	 * @param srcSheet  源工作表
	 * @param destSheet 目标工作表
	 */
	protected void mergerRegion(Sheet srcSheet, Sheet destSheet) {
		int sheetMergerCount = srcSheet.getNumMergedRegions();
		for (int i = 0; i < sheetMergerCount; i++) {
			destSheet.addMergedRegion(srcSheet.getMergedRegion(i));
		}
	}

}
